package org.lsj.kit.config.SpringSecurityImpl;

import org.lsj.kit.mapper.PermMapper;
import org.lsj.kit.mapper.RoleMapper;
import org.lsj.kit.mapper.UserMapper;
import org.lsj.kit.model.Perm;
import org.lsj.kit.model.Role;
import org.lsj.kit.model.User;
import org.lsj.kit.model.UserExample;
import org.lsj.kit.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by lishengjie on 2019/3/3.
 */
@Component("userDetailsService")
public class KitUserDetailService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermMapper permMapper;
    @Autowired
    private MenuService menuService;
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        List<Map<String, Object>> permTree;
        Map<Integer,List<String>> buttonMap;

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        List<User> users = userMapper.selectByExample(userExample);
        if (CollectionUtils.isEmpty(users)) {
            return null;
        }
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        List<Role> roles = roleMapper.queryByUserId(users.get(0).getId());
        roles.forEach(role -> {
            SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
            grantedAuthorities.add(grantedAuthority);
        });
        User dbUser = users.get(0);

        List<Perm> permList= permMapper.queryByUserId(dbUser.getId());
        permTree = menuService.permToTree(null, false, permList);

        Map<String,Object> params = new HashMap<>();
        params.put("userId",dbUser.getId());
        List<Map<String, Object>> permResources = permMapper.queryMenuResourceByUserId(params);
        buttonMap = resourceToButtonMap(permResources);
        KitUserDetails userDetails = new KitUserDetails(dbUser,dbUser.getUserName(),dbUser.getPassword(),true,true,true,true,grantedAuthorities,permTree,buttonMap);
        return userDetails;
    }

    private Map<Integer, List<String>> resourceToButtonMap(List<Map<String,Object>> resourceList) {
        Map<Integer,List<String>> buttonMap=new HashMap<>();
        for(Map resource:resourceList){
            Integer permId = (Integer)resource.get("permId");
            String buttonCode = (String)resource.get("buttonCode");
            List<String> buttonList=buttonMap.get(permId);
            if(buttonList==null){
                buttonList = new ArrayList<>();
                buttonMap.put(permId,buttonList);
            }
            buttonList.add(buttonCode);
        }
        return buttonMap;
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encode = encoder.encode("123456");
        System.out.println(encode);
    }
}
